/*
 * Protocol.c
 *
 *  Created on: 2014-3-11
 *      Author: Mahome、Hedark(reviser)
 *
 *	revised 2017.9.9 Hedark ,unified the all the sorts of format.
 *  Add unified ACK SID,removed the useless types.
 *
 */

#include "BSW_Include.h"
ubyte Message_IMEI15[15];//15位IMEI号
uint8_t GPRS_SendBuff[500];//GPRS的发送buff
uint16_t GPRS_SendLength=0;
//车速_用于统计
#define VehicleSpeedForStatic	((float)((((uword)TIU_Res.CANData_Res[134])<<8)|TIU_Res.CANData_Res[133]))*0.00390625
//发动机转速_用于统计
#define MotorSpeedForStatic   (uword)(((float)((((uword)TIU_Res.CANData_Res[218])<<8)|TIU_Res.CANData_Res[217]))*0.125)
//用于设计统计算法的速度阈值
#define gongkuangyuzhi         1
extern ubyte MotorStart_Refresh_Flag ;

ubyte ADC_SampleADC_Index[4] = {0,0,0,0};
uword ADC_Averager[4];
ulong ADC_Averager_temp[4];
ubyte NEW_CAN0 = 0;
ubyte NEW_CAN1 = 0;
static ubyte CAN0_EnableNum = 0;
static ubyte CAN1_EnableNum = 0;
ResponseStr TIU_Res;
StrStatistics ConditionStatistics;

strW2B W2B;
strL2B L2B;

void Protocol_CANInitial(void)
{
#ifdef NewProtocalDebug
	Enable_CAN_TR0;
	Enable_CAN_TR1;
#endif
	for(ubyte i=0;i<30;i++)
		if(CH1_MO[i].EnableCtr == MoEnable)	CAN0_EnableNum++;
	for(ubyte i=0;i<30;i++)
		if(CH2_MO[i].EnableCtr == MoEnable) CAN1_EnableNum++;
}

/***************************更新TIU_Res中的GPS信息和IMEI信息*******************************/
//包长（2byte）+PID个数(2byte)+SID+PID+8个字节数据
void UpDateGPS_IMEI_Time(void)
{
	//更新GPS
	TIU_Res.GPS_Len=27+4;
	TIU_Res.GPS_Res[0]=0x00;//子包长度
	TIU_Res.GPS_Res[1]=27+4;//子包长度
	TIU_Res.GPS_Res[2]=0x00;//PID个数
	TIU_Res.GPS_Res[3]=0x01;//PID个数
	TIU_Res.GPS_Res[4]=0x62;//SID
	TIU_Res.GPS_Res[5]=0x01;//PID

	for(ubyte i=0;i<9;i++)	TIU_Res.GPS_Res[6+i]=GPS_Info.GPS_Ninfo[i];
	TIU_Res.GPS_Res[15]=GPS_Info.GPS_NorS;
	for(ubyte i=0;i<10;i++)	TIU_Res.GPS_Res[16+i]=GPS_Info.GPS_Einfo[i];
	TIU_Res.GPS_Res[26]=GPS_Info.GPS_EorW;
	TIU_Res.GPS_Res[27]=(ubyte)(GPS_Info.Speed>>8);
	TIU_Res.GPS_Res[28]=(ubyte)(GPS_Info.Speed);
	TIU_Res.GPS_Res[29]=(ubyte)(GPS_Info.Hight>>8);
	TIU_Res.GPS_Res[30]=(ubyte)(GPS_Info.Hight);

	TIU_Res.IMEI_Time_Len=28;
	TIU_Res.IMEI_Time_Res[0]=0x00;
	TIU_Res.IMEI_Time_Res[1]=28;
	TIU_Res.IMEI_Time_Res[2]=0x00;
	TIU_Res.IMEI_Time_Res[3]=0x02;
	TIU_Res.IMEI_Time_Res[4]=0x63;
	TIU_Res.IMEI_Time_Res[5]=0x0;
	TIU_Res.IMEI_Time_Res[6]=(ubyte)GPS_Info.Time.wYear;
	TIU_Res.IMEI_Time_Res[7]=(ubyte)GPS_Info.Time.wMonth;
	TIU_Res.IMEI_Time_Res[8]=(ubyte)GPS_Info.Time.wDay;
	TIU_Res.IMEI_Time_Res[9]=(ubyte)GPS_Info.Time.wHour;
	TIU_Res.IMEI_Time_Res[10]=(ubyte)GPS_Info.Time.wMinute;
	TIU_Res.IMEI_Time_Res[11]=(ubyte)GPS_Info.Time.wSecond;
	TIU_Res.IMEI_Time_Res[12]=0x01;
	for(ubyte i=0;i<15;i++)
	{
		TIU_Res.IMEI_Time_Res[13+i]=Message_IMEI15[i];
	}
}

/***************************更新TIU_Res中的统计信息******************************************/
//包长（2byte）+PID个数(2byte)+SID+PID+8个字节数据
void UpDateCANData(void)	//需要根据Enable的CANID个数自动进行打包
{
	listStorenode_t* CANTempVol;
	static ubyte Tempidx = 0;
	static ubyte Volidx = 0;

	for(ubyte i=0;i<30;i++)
		if(CH1_MO[i].EnableCtr == MoEnable)
		{
			TIU_Res.CANData_Res[5+i*9] = i;
			for(ubyte k=0;k<8;k++)	TIU_Res.CANData_Res[5+i*9+k+1] = CANRxData[i][k];
		}
	for(ubyte i=0;i<30;i++)
		if(CH2_MO[i].EnableCtr == MoEnable)
		{
			TIU_Res.CANData_Res[5+(i+CAN0_EnableNum)*9] = i+CAN0_EnableNum;
			for(ubyte k=0;k<8;k++)	TIU_Res.CANData_Res[5+(i+CAN0_EnableNum)*9+k+1] = CANRxData[i+30][k];
		}

	for(ubyte i=0;i<TempPackLen;i++)
	{
		CANTempVol = llfindbyKey_CanList(Tempidx,Temp);
		if(++Tempidx>=MaxTempCNT)			Tempidx = 0;

		TIU_Res.CANData_Res[5+(i+CAN0_EnableNum+CAN1_EnableNum)*9] = i+CAN0_EnableNum+CAN1_EnableNum;
		if(CANTempVol!=NULL)
			for(ubyte k=0;k<8;k++)	TIU_Res.CANData_Res[5+(i+CAN0_EnableNum+CAN1_EnableNum)*9+k+1] = CANTempVol->msg.data[k];
		else
		{
			for(ubyte k=0;k<8;k++)	TIU_Res.CANData_Res[5+(i+CAN0_EnableNum+CAN1_EnableNum)*9+k+1] = 0;
//			SEGGER_RTT_printf(0, "Tmp don't have not this key,\r\n");
		}


	}
	for(ubyte i=0;i<VolPackLen;i++)
	{
		CANTempVol = llfindbyKey_CanList(Volidx,Voltage);
		if(++Volidx>=MaxVolCNT) 			Volidx = 0;

		TIU_Res.CANData_Res[5+(i+CAN0_EnableNum+CAN1_EnableNum+TempPackLen)*9] = i+CAN0_EnableNum+CAN1_EnableNum+TempPackLen;
		if(CANTempVol!=NULL)
			for(ubyte k=0;k<8;k++)	TIU_Res.CANData_Res[5+(i+CAN0_EnableNum+CAN1_EnableNum+TempPackLen)*9+k+1] = CANTempVol->msg.data[k];
		else
		{
			for(ubyte k=0;k<8;k++)	TIU_Res.CANData_Res[5+(i+CAN0_EnableNum+CAN1_EnableNum+TempPackLen)*9+k+1] = 0;
//			SEGGER_RTT_printf(0, "Vol don't have not this key,\r\n");
		}

	}

	TIU_Res.CANData_Len=(CAN0_EnableNum+CAN1_EnableNum+TempPackLen+VolPackLen)*9+5;

	TIU_Res.CANData_Res[0]=TIU_Res.CANData_Len>>8;
	TIU_Res.CANData_Res[1]=(ubyte)TIU_Res.CANData_Len;
	TIU_Res.CANData_Res[2]=0x00;
	TIU_Res.CANData_Res[3]=(CAN0_EnableNum+CAN1_EnableNum);
	TIU_Res.CANData_Res[4]=0x60;

#ifdef NewProtocalDebug
	SEGGER_RTT_printf(0, "CAN data Length: %u,\r\n", TIU_Res.CANData_Len);
	for(unsigned int kk=0;kk<TIU_Res.CANData_Len;kk++)
		SEGGER_RTT_printf(0, "0x%02X ", TIU_Res.CANData_Res[kk]);
	SEGGER_RTT_printf(0, "\r\n");
#endif

}

/***************************更新TIU_Res中的统计信息*******************************/
//包长（2byte）+PID个数(2byte)+SID+PID+8个字节数据
void UpDateConditionStatistic(void)
{
	uint16_t idx = 0;
	StatisStr VS,V,I;
//		TIU_Res.ConStat_Len=22;
	TIU_Res.ConStat_Res[idx++]=0x00;
	TIU_Res.ConStat_Res[idx++]=TIU_Res.ConStat_Len;//
	TIU_Res.ConStat_Res[idx++]=0x00;//
	TIU_Res.ConStat_Res[idx++]=0x01;//0001个CANID
	TIU_Res.ConStat_Res[idx++]=0x64;//SID代表状态信息

	TIU_Res.ConStat_Res[idx++]=0x00;//PID = 0;

	VS = StatisVehicleSpeed;
	V = StatisVoltage;
	I = StatisCurrents;
	StatisVehicleSpeed.cnt = 0;
	StatisVehicleSpeed.total.F = 0;
	StatisVoltage.cnt = 0;
	StatisVoltage.total.F = 0;
	StatisCurrents.cnt = 0;
	StatisCurrents.total.F = 0;
	if(VS.cnt>0)
		VS.total.F = VS.total.F/VS.cnt;
	else
		for(ubyte i=0;i<4;i++)
			VS.total.B[i] = 0;

	if(V.cnt>0)
	{
		V.total.F = V.total.F/V.cnt;
			if(I.cnt>0)
				I.total.F = I.total.F/I.cnt;
		I.total.F = I.total.F*V.total.F;
	}
	else
		for(ubyte i=0;i<4;i++)
			I.total.B[i] = 0;

	VS.total.F = VS.total.F/3.6*(UploadPeriod/1000); // Unit is m
	I.total.F = I.total.F*(UploadPeriod/1000); // Unit is J
	for(ubyte i=0;i<4;i++)
		TIU_Res.ConStat_Res[idx++] = VS.total.B[i];
	for(ubyte i=0;i<4;i++)
		TIU_Res.ConStat_Res[idx++] = I.total.B[i]/(UploadPeriod/1000);
	TIU_Res.ConStat_Len = idx;
}



/***************************更新TIU_Res中的ADC信息******************************************/
//包长（2byte）+PID个数(2byte)+SID+PID+8个字节数据
void UpDateADCData(void)
{
    TIU_Res.ADCData_Len = 14;
	TIU_Res.ADCData_Res[0] = 0;
	TIU_Res.ADCData_Res[1] = 14;
	TIU_Res.ADCData_Res[2] = 0;
	TIU_Res.ADCData_Res[3] = 1;
	TIU_Res.ADCData_Res[4] = 0x61;
	TIU_Res.ADCData_Res[5] = 0x01;
	for(ubyte i=0;i<8;i++)
	{
		TIU_Res.ADCData_Res[6+i] = *((ubyte*)(&ADC_Averager)+i);
	}
}


void FlashLED_100msTask(ubyte lightTimes)		//lightTimes 这个参数代表闪烁的频率
{
	static ubyte lightTimesCNT=0;
	if(lightTimesCNT++>=lightTimes)
	{
		//如果卫星数目大于等于3颗，闪烁GPSd灯
		if(GPS_Info.num_satellites>=2)  			Toggle_GPS_LED;
		//如果已经稳定连接闪烁GPRS灯
//		if(stateEnable==2&&connectState==2)		Toggle_GPRS_LED;
		//如果SD卡可以成功写入闪烁SD卡灯
//		if(SDWriteScuccess_LED_Flag==1)
//		{
//			Toggle_SD_LED;//翻转SD卡指示灯，指示成功写入SD信息
//			SDWriteScuccess_LED_Flag=0;
//		}
		//如果有新的CAN NOD1消息那么闪烁CAN NOD1灯
		if(NEW_CAN0 ==1)
		{
			Toggle_CAN0_LED;//翻转LED灯指示接收到CAN消息
			NEW_CAN0 = 0;
		}
		//如果有新的CAN NOD2消息那么闪烁CAN NOD2灯
		if(NEW_CAN1 ==1)
		{
			Toggle_CAN1_LED;//翻转LED灯指示接收到CAN消息
			NEW_CAN1 = 0;
		}
		//如果有新的CAN NOD3消息那么闪烁CAN NOD3灯

		//如果有新的CAN NOD4消息那么闪烁CAN NOD4灯

		//如果程序运行，直接闪烁runing 的指示灯
		lightTimesCNT=0;
	}
}

//将所有数据更新到一个统一的buffer TIU_Res中
void UpdateTIU_Res_100msTask(void)
{
	UpDateGPS_IMEI_Time();
	UpDateConditionStatistic();
	UpDateCANData();
	UpDateADCData();
}

uword CheckSumReturnUINT(uword Num,ubyte* StardAdd)
{
	uword CheckSum = 0;
	for(uword i=0;i<Num;i++)	CheckSum +=*(StardAdd+i);
	return(CheckSum);
}
/**************************01-打包每一类的数据*************************************************************************/
void Pack_SIDGPRS(uword Len, ubyte* Res)
{
	if(Len!=0)
	{
		for(uword i=0;i<Len;i++)
			GPRS_SendBuff[GPRS_SendLength++]=*(Res++);
	}
}
/***************************02-将TIU_Res 中需要发送的数据进行汇总到GPRS_SendBuff中准备发送*******************************/
void Pack_GPRS(void)
{

	strW2B W2B;
	GPRS_SendBuff[GPRS_SendLength++] = GetIP_Num();
    //GPS---SID=0x62
    Pack_SIDGPRS(TIU_Res.GPS_Len, (ubyte*)&TIU_Res.GPS_Res);
    //TimeIMEI -SID=0x63
    Pack_SIDGPRS(TIU_Res.IMEI_Time_Len, (ubyte*)&TIU_Res.IMEI_Time_Res);
    //KST021-SID==0x64
    Pack_SIDGPRS(TIU_Res.ConStat_Len, (ubyte*)&TIU_Res.ConStat_Res);
    //KST021-CAN Monitor-SID=0x60
    Pack_SIDGPRS(TIU_Res.CANData_Len, (ubyte*)&TIU_Res.CANData_Res);
    W2B.W = GPRS_SendLength-2;
    GPRS_SendBuff[0] = W2B.B[0];
    GPRS_SendBuff[1] = W2B.B[1];
    General_Respone2Server(&GPRS_SendBuff[0],GPRS_SendLength);//,Monitor.MainCNT, Monitor.SubCNT,Ftyp_DAQ, Styp_MON ,Monitor.Des,Monitor.Source);
    GPRS_SendLength = 0;

}

void Pack_GPRS4Rec(void)
{
	strW2B W2B;
	GPRS_SendBuff[GPRS_SendLength++] = 1;
    GPRS_SendBuff[GPRS_SendLength++] = 0;
    GPRS_SendBuff[GPRS_SendLength++] = 0xEE;	//SID monitor 里面的EE
    GPRS_SendBuff[GPRS_SendLength++]=TIU_Res.IPNum++;
    //GPS---SID=0x62
    Pack_SIDGPRS(TIU_Res.GPS_Len, (ubyte*)&TIU_Res.GPS_Res);
    //TimeIMEI -SID=0x63
    Pack_SIDGPRS(TIU_Res.IMEI_Time_Len, (ubyte*)&TIU_Res.IMEI_Time_Res);
    //KST021-SID==0x64
    Pack_SIDGPRS(TIU_Res.ConStat_Len, (ubyte*)&TIU_Res.ConStat_Res);
    //KST021-CAN Monitor-SID=0x60
    Pack_SIDGPRS(TIU_Res.CANData_Len, (ubyte*)&TIU_Res.CANData_Res);
    W2B.W = GPRS_SendLength-2;
    GPRS_SendBuff[0] = W2B.B[0];
    GPRS_SendBuff[1] = W2B.B[1];
    General_Respone2Server4Rec(&GPRS_SendBuff[0],GPRS_SendLength);//,Monitor.MainCNT, Monitor.SubCNT,Ftyp_DAQ, Styp_MON ,Monitor.Des,Monitor.Source);
    GPRS_SendLength = 0;
}

void GetIMEI(ubyte* data,uword Len)
{
	for(uword i=0;i<Len-5;i++)
	{
		if((data[i]=='I')&(data[i+1]=='M')&(data[i+2]=='E')&(data[i+3]=='I'))
		{
			for(ubyte j=0;j<15;j++)	Message_IMEI15[j]= data[6+i+j];
			break;
		}
	}
}

